package com.kingtone.rongji.pay.weixin;

import java.io.StringReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.xmlpull.v1.XmlPullParser;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.util.Xml;
import android.widget.Toast;
import com.kingtone.rongji.R;
import com.kingtone.rongji.tool.AppContasts;
import com.kingtone.rongji.tool.RongJiUtils;
import com.tencent.mm.sdk.modelpay.PayReq;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;

public class WeiXinPayActivity extends Activity
{

	private static final String TAG = WeiXinPayActivity.class.getSimpleName();
	private Context context = WeiXinPayActivity.this;
	final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);
	PayReq req = null;
	private String body = null;//商品描述
	private int price= 0;//商品价格
	Map<String, String> resultunifiedorder;
	private MessageReceiver messageReceiver;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.weixin_pay);
		Intent intent = getIntent();
		this.body = intent.getStringExtra("body");
		this.price = (int) (intent.getDoubleExtra("price", 0.00) * 100);
		req = new PayReq();

		msgApi.registerApp(Constants.APP_ID);
		// 生成prepay_id
		GetPrepayIdTask getPrepayId = new GetPrepayIdTask();
		getPrepayId.execute();
		//String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
		
		messageReceiver = new MessageReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(AppContasts.BROADCAST_ACTION_CLOSE_ACTIVITY);
        registerReceiver(messageReceiver, filter);
	}

	/**
	 * 生成签名
	 */

	private String genPackageSign(List<NameValuePair> params)
	{
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < params.size(); i++)
		{
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(Constants.API_KEY);

		String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
		return packageSign;
	}

	private String genAppSign(List<NameValuePair> params)
	{
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < params.size(); i++)
		{
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(Constants.API_KEY);

		String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
		Log.e("orion", appSign);
		return appSign;
	}

	private String toXml(List<NameValuePair> params)
	{
		StringBuilder sb = new StringBuilder();
		sb.append("<xml>");
		for (int i = 0; i < params.size(); i++)
		{
			sb.append("<" + params.get(i).getName() + ">");

			sb.append(params.get(i).getValue());
			sb.append("</" + params.get(i).getName() + ">");
		}
		sb.append("</xml>");

		Log.e("orion", sb.toString());
		return sb.toString();
	}

	private class GetPrepayIdTask extends AsyncTask<Void, Void, Map<String, String>>
	{
		@Override
		protected void onPreExecute()
		{
			RongJiUtils.showEmptyProgress(context);
		}

		@Override
		protected void onPostExecute(Map<String, String> result)
		{
			if (result != null && result.containsKey("result_code")) {
				String resultCode = result.get("result_code");
				if(resultCode.equals("SUCCESS"))
				{
					resultunifiedorder = result;
					//生产签名参数
					genPayReq();
				}else
				{
					Toast.makeText(context, "支付失败", Toast.LENGTH_SHORT).show();
					finish();
				}
			}
			

		}

		@Override
		protected void onCancelled()
		{
			super.onCancelled();
		}

		@Override
		protected Map<String, String> doInBackground(Void... params)
		{

			String url = String.format("https://api.mch.weixin.qq.com/pay/unifiedorder");
			String entity = genProductArgs();

			Log.e("orion", entity);

			byte[] buf = Util.httpPost(url, entity);

			String content = new String(buf);
			Log.e("orion", content);
			Map<String, String> xml = decodeXml(content);

			return xml;
		}
	}

	public Map<String, String> decodeXml(String content)
	{
		try
		{
			Map<String, String> xml = new HashMap<String, String>();
			XmlPullParser parser = Xml.newPullParser();
			parser.setInput(new StringReader(content));
			int event = parser.getEventType();
			while (event != XmlPullParser.END_DOCUMENT)
			{

				String nodeName = parser.getName();
				switch (event)
				{
				case XmlPullParser.START_DOCUMENT:

					break;
				case XmlPullParser.START_TAG:

					if ("xml".equals(nodeName) == false)
					{
						// 实例化student对象
						xml.put(nodeName, parser.nextText());
					}
					break;
				case XmlPullParser.END_TAG:
					break;
				}
				event = parser.next();
			}

			return xml;
		} catch (Exception e)
		{
			Log.e("orion", e.toString());
		}
		return null;

	}

	private String genNonceStr()
	{
		Random random = new Random();
		return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
	}

	private long genTimeStamp()
	{
		return System.currentTimeMillis() / 1000;
	}

	private String genOutTradNo()
	{
		Random random = new Random();
		return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
	}

	//
	private String genProductArgs()
	{
		StringBuffer xml = new StringBuffer();

		try
		{
			String nonceStr = genNonceStr();

			xml.append("</xml>");
			List<NameValuePair> packageParams = new LinkedList<NameValuePair>();
			packageParams.add(new BasicNameValuePair("appid", Constants.APP_ID));
			packageParams.add(new BasicNameValuePair("body", body));
			packageParams.add(new BasicNameValuePair("mch_id", Constants.MCH_ID));
			packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
			packageParams.add(new BasicNameValuePair("notify_url", "http://m.rongji365.com/WxTrade/TenPayV3/PayNotifyUrl"));
			packageParams.add(new BasicNameValuePair("out_trade_no", genOutTradNo()));
			packageParams.add(new BasicNameValuePair("spbill_create_ip", "127.0.0.1"));
			packageParams.add(new BasicNameValuePair("total_fee", ""+price));
			packageParams.add(new BasicNameValuePair("trade_type", "APP"));

			String sign = genPackageSign(packageParams);
			packageParams.add(new BasicNameValuePair("sign", sign));

			String xmlstring = toXml(packageParams);

			return xmlstring;

		} catch (Exception e)
		{
			Log.e(TAG, "genProductArgs fail, ex = " + e.getMessage());
			return null;
		}

	}

	private void genPayReq()
	{
		req.appId = Constants.APP_ID;
		req.partnerId = Constants.MCH_ID;
		req.prepayId = resultunifiedorder.get("prepay_id");
		req.packageValue = "Sign=WXPay";
		req.nonceStr = genNonceStr();
		req.timeStamp = String.valueOf(genTimeStamp());

		List<NameValuePair> signParams = new LinkedList<NameValuePair>();
		signParams.add(new BasicNameValuePair("appid", req.appId));
		signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));
		signParams.add(new BasicNameValuePair("package", req.packageValue));
		signParams.add(new BasicNameValuePair("partnerid", req.partnerId));
		signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
		signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));

		req.sign = genAppSign(signParams);
		//去支付
		sendPayReq();

	}

	private void sendPayReq()
	{
		msgApi.registerApp(Constants.APP_ID);
		msgApi.sendReq(req);
	}
	
	 /**
		 * @brief 消息广播通知
		 */
		public class MessageReceiver extends BroadcastReceiver 
		{
	        @Override
	        public void onReceive(Context arg0, Intent arg1) 
	        {
	             finish();
	        }
	    }

}
